package com.ruoyi.base.config;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.dyun.tool.jwt.registry.SecureRegistry;
import com.ruoyi.base.filter.TenantReqFilter;
import com.ruoyi.common.enums.BaseStatusEnum;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import net.dreamlu.mica.props.MicaUploadProperties;
import org.apache.ibatis.reflection.MetaObject;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

import java.util.Date;

/**
 * MybatisPlus配置
 *
 * @author dyun
 */
@Slf4j
@AllArgsConstructor
@Configuration
@MapperScan("com.ruoyi.**.mapper")
public class MybatisPlusConfig {
    private final MicaUploadProperties micaUploadProperties;

    /**
     * websocket配置
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

    @Bean
    public WxMpMessageRouter messageRouter(WxMpService wxMpService) {
        return new WxMpMessageRouter(wxMpService);
    }

    @SuppressWarnings({"rawtypes", "unchecked"})
    @Bean
    public FilterRegistrationBean tenantReqFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new TenantReqFilter());
        registration.addUrlPatterns("/*");
        registration.setName("tenantReqFilter");
        registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE);
        return registration;
    }

    @Bean
    public SecureRegistry secureRegistry() {
        SecureRegistry secureRegistry = new SecureRegistry();
        secureRegistry.excludePathPatterns(micaUploadProperties.getUploadPathPattern());
        secureRegistry.excludePathPatterns("/openapi/**");
        secureRegistry.excludePathPatterns("/demo/**");
        secureRegistry.excludePathPatterns("/wx/public/**");
        return secureRegistry;
    }

    @Component
    public class MPMetaObjectHandler implements MetaObjectHandler {

        @Override
        public void insertFill(MetaObject metaObject) {
            // System.out.println("插入方法实体填充")

            Date now = new Date();
            this.setFieldValByName("createTime", now, metaObject);
            this.setFieldValByName("isDeleted", BaseStatusEnum.DB_NOT_DELETED.getStatus(), metaObject);
        }

        @Override
        public void updateFill(MetaObject metaObject) {
            // System.out.println("更新方法实体填充")

            Date now = new Date();
            this.setFieldValByName("updateTime", now, metaObject);
        }

        /**
         * 填充值，先判断是否有手动设置，优先手动设置的值，例如：job必须手动设置
         *
         * @param fieldName  属性名
         * @param fieldVal   属性值
         * @param metaObject MetaObject
         */
        private void fillValIfNullByName(String fieldName, Object fieldVal, MetaObject metaObject) {
            // 用户手动设置的值
            Object userSetValue = this.getFieldValByName(fieldName, metaObject);
            if (userSetValue != null) {
                return;
            }
            this.setFieldValByName(fieldName, fieldVal, metaObject);
        }
    }
}
